package com.smartplatform.event.listener;

import com.smartplatform.event.LoginEvent;
import com.smartplatform.pojo.SysLogininfor;
import com.smartplatform.pojo.SysUserOnline;
import com.smartplatform.service.SysUserOnlineService;
import com.smartplatform.service.SysUserService;
import com.smartplatform.service.UserLoginlogService;
import com.smartplatform.utils.RequestUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Author 咕唧
 * @Date 2022/5/27 20:49
 * @Version 1.0
 */
@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)//声明创建对象模式为单例
public class LoginListener {

    private SysUserService sysUserService;
    //用户在线记录
    private SysUserOnlineService sysUserOnlineService;
    //用户登录日志
    private UserLoginlogService userLoginlogService;

    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    public void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor) {
        this.threadPoolExecutor = threadPoolExecutor;
    }

    @Autowired
    public void setSysUserService(SysUserService sysUserService) {
        this.sysUserService = sysUserService;
    }

    @Autowired
    public void setSysUserOnlineService(SysUserOnlineService sysUserOnlineService) {
        this.sysUserOnlineService = sysUserOnlineService;
    }

    @Autowired
    public void setUserLoginlogService(UserLoginlogService userLoginlogService) {
        this.userLoginlogService = userLoginlogService;
    }

    //监听登录
    @EventListener
    public void onEvent(LoginEvent event) {
        System.err.println("收到一个登录事件" + event);
        //获取当前登录用户
        String username = event.getUsername();
        //记录用户ip等信息保存到数据库中，使用异步线程处理
        //使用springmvc提供的threadLocal保存request请求对象
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取request中的登录数据,比如ip ,系统,浏览器等信息
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String sessionId = request.getSession().getId();
        //获取操作系统和浏览器信息
        Map<String, String> osAndBrowserInfo = RequestUtil.getOsAndBrowserInfo(request);
        String ip = RequestUtil.getRemoteHost(request);
        //设置当前时间
        Date processDate = new Date();
        //开启一个新线程执行获取ip等操作操作
        CompletableFuture.runAsync(() -> {
            //获取ip所在的地区
            String locationByIp = RequestUtil.getLocationByIp(ip);
            //保存日志信息
            SysLogininfor sysLogininfor = new SysLogininfor();
            sysLogininfor.setLoginName(username);
            //设置操作系统和浏览器
            sysLogininfor.setBrowser(osAndBrowserInfo.get("browser"));
            sysLogininfor.setOs(osAndBrowserInfo.get("os"));
            //设置登录的时间
            sysLogininfor.setLoginTime(processDate);
            //设置登录的ip
            sysLogininfor.setIpaddr(ip);
            //设置登录地址
            sysLogininfor.setLoginLocation(locationByIp);
            switch (event.getType()) {
                case FAIL:
                    sysLogininfor.setMsg("用户名密码错误");
                    sysLogininfor.setStatus("0");
                    break;
                case SUCCESS:
                    sysLogininfor.setMsg("登录成功");
                    sysLogininfor.setStatus("1");
                    break;
            }
            //记录设备在线信息
            SysUserOnline sysUserOnline = new SysUserOnline();
            //把信息复制到设备在线表中
            BeanUtils.copyProperties(sysLogininfor, sysUserOnline);
            sysUserOnline.setSessionId(sessionId);
            sysUserOnline.setStartTimestamp(processDate);
            sysUserOnline.setExpireTime(30L);
            //记录用户在线数据，每个用户只会存在一条数据
            sysUserOnlineService.insertUserOnline(sysUserOnline);
            //记录用户登录日志,每次登录都会添加新的数据
            userLoginlogService.insertUserLogin(sysLogininfor);
        },threadPoolExecutor);

        switch (event.getType()) {
            case SUCCESS:
                //更新用户的登录时间和ip
                CompletableFuture.runAsync(() -> {
                    sysUserService.updateLogin(username, processDate, ip);
                },threadPoolExecutor);
                break;
        }

    }
}
